﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using daq_test_cs;
using static daq_test_cs.DAQ217Wrapper;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

public static class IntPtrExtensions
{
    public static byte[] IntPtrToByteArray(IntPtr ptr, int length)
    {
        var array = new byte[length];
        Marshal.Copy(ptr, array, 0, length);
        return array;
    }
}


public class Program
{
    public static void DAQ217()
    {
        var device = DAQ217Wrapper.DAQ217_New();
        var usb_server = USBServerWrapper.USBServer_New(USBServerWrapper.DeviceType.DeviceType_DAQ217);
        if (usb_server == IntPtr.Zero)
        {
            Console.WriteLine("usb server is null");
            return;
        }
        USBServerWrapper.USBServer_StartSearch(usb_server);
        byte bus_count = 0;
        IntPtr bus_numbersIntPtr = USBServerWrapper.USBServer_GetBusNumbers(usb_server, out bus_count);
        byte[] bus_numbers = IntPtrExtensions.IntPtrToByteArray(bus_numbersIntPtr, bus_count);
        Console.WriteLine($"发现 {bus_count} 个设备");

        try
        {
            if(bus_count == 0)
            {
                return;
            }
            // 遍历bus_numbers并获取每个总线上的设备地址
            foreach (var busNumber in bus_numbers)
            {
                byte deviceCount = 0;
                IntPtr deviceAddressesIntPtr = USBServerWrapper.USBServer_GetDeviceAddresses(usb_server, busNumber, out deviceCount);
                if (deviceAddressesIntPtr == IntPtr.Zero)
                {
                    Console.WriteLine($"No devices found on Bus Number: {busNumber}");
                    continue;
                }
                Console.WriteLine($"获取设备地址：发现 {deviceCount} 个设备，设备号为: {busNumber}");

                byte[] deviceAddresses = IntPtrExtensions.IntPtrToByteArray(deviceAddressesIntPtr, deviceCount);

                // 打印或处理每个设备地址
                foreach (byte deviceAddress in deviceAddresses)
                {
                    Console.WriteLine($"设备 {busNumber} 的地址为: {deviceAddress}");

                    var socket = USBServerWrapper.USBServer_GetClient(usb_server, busNumber, deviceAddress);
                    if (socket == IntPtr.Zero)
                    {
                        Console.WriteLine($"获取设备失败，总线号: {busNumber}, 设备地址: {deviceAddress}");
                        continue;
                    }

                    if (!DAQ217Wrapper.DAQ217_UseBackend(device, socket))
                    {
                        Console.WriteLine($"Failed to use backend for Bus Number: {busNumber}, Device Address: {deviceAddress}");
                        continue;
                    }

                    if (!DAQ217Wrapper.DAQ217_InitializeDevice(device))
                    {
                        Console.WriteLine($"Failed to initialize device for Bus Number: {busNumber}, Device Address: {deviceAddress}");
                        continue;
                    }

                    if (!DAQ217Wrapper.DAQ217_ConnectedDevice(device))
                    {
                        Console.WriteLine($"Failed to connect device for Bus Number: {busNumber}, Device Address: {deviceAddress}");
                        continue;
                    }

                    Console.WriteLine($"已连接到设备的总线号码: {busNumber}, 设备地址: {deviceAddress}");
                    break;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生错误，错误代码: {ex.Message}");
        }

        // 延时100ms
        Thread.Sleep(100);

        // 配置触发模式
        int triggerType = (int)LockzhinerADCTriggerType.RisingEdge;//上升沿触发
        int triggerMode = (int)LockzhinerADCTriggerMode.Common;//普通触发模式
        int triggerChannel = (int)LockzhinerADCChannel.ADCChannelAINNone;//软件触发
        int triggerLevel = 300;
        bool result_TriggerType = DAQ217Wrapper.DAQ217_ConfigADCTrigger(device, triggerType, triggerMode, triggerChannel, triggerLevel);
        if (result_TriggerType)
        {
            Console.WriteLine("ADC 触发配置成功！");
        }
        else
        {
            Console.WriteLine("ADC 触发配置失败！");
        }

        //配置采样率
        int sampleRate = (int)LockzhinerADCSampleRate.ADCSampleRate_10_M;
        bool result_SampleRate = DAQ217Wrapper.DAQ217_ConfigADCSampleRate(device, sampleRate);
        if (result_SampleRate)
        {
            Console.WriteLine("采样率配置成功！");
        }
        else
        {
            Console.WriteLine("采样率配置失败！");
        }

        // 配置电压量程
        int adcVoltage = (int)LockzhinerADCVoltage.ADCVoltage_10_V;
        bool result_ADCVoltage = DAQ217Wrapper.DAQ217_ConfigADCVoltage(device, adcVoltage);
        if (result_ADCVoltage)
        {
            Console.WriteLine("电压量程配置成功！");
        }
        else
        {
            Console.WriteLine("电压量程配置失败！");
        }

        // 配置触发长度 
        uint triggerLength = 49600;
        bool result_TriggerLength = DAQ217Wrapper.DAQ217_ConfigADCTriggerLength(device, triggerLength);
        if (result_TriggerLength)
        {
            Console.WriteLine("触发长度配置成功！");
        }
        
        // 配置触发超时
        uint triggerTimeout = 100;
        bool result_TriggerTimeout = DAQ217Wrapper.DAQ217_ConfigTriggerTimeout(device, triggerTimeout);
        if (result_TriggerTimeout)
        {
            Console.WriteLine("触发超时配置成功！");
        }
        else
        {
            Console.WriteLine("触发超时配置失败！");
        }

        // 配置ADC通道 每位代表1个通道 1代表使能，0代表失能。从右往左分别为1~4通道，多通道自动顺延位置
        byte adcChannel = 0b00001111;
        bool result_ADCChannel = DAQ217Wrapper.DAQ217_ConfigADCChannel(device, adcChannel);
        if (result_ADCChannel)
        {
            Console.WriteLine("ADC通道配置成功！");
        }
        else
        {
            Console.WriteLine("ADC通道配置失败！");
        }

        // 配置ACDC模式
        byte acdcMode = 1;
        bool result_ACDCMode = DAQ217Wrapper.DAQ217_ConfigACDC(device, acdcMode);
        if (result_ACDCMode)
        {
            Console.WriteLine("ACDC模式配置成功！");
        }
        else
        {
            Console.WriteLine("ACDC模式配置失败！");
        }

        // 开始采集
        if(!DAQ217_StartCollection(device)){
            Console.WriteLine("开始采集失败");
            return;
        }

        // 延时100ms
        Thread.Sleep(100);

        // 软件触发
        if(!DAQ217_ConfigADCTriggerSource(device)){
            Console.WriteLine("软件触发失败");
            return;
        }

        // 采集数据
        uint readSize = triggerLength; // 使用之前配置的触发长度作为读取大小
        float[][] channelData = new float[4][]; // 为4个通道创建数据数组
        for (int i = 0; i < 4; i++)
        {
            channelData[i] = new float[readSize];
        }

        Console.WriteLine("开始读取数据...");
        
        // 创建取消令牌源，用于控制线程停止
        using (var cts = new CancellationTokenSource())
        {
            // 创建4个线程来读取数据
            var tasks = new Task[4];
            for (byte channel = 0; channel < 4; channel++)
            {
                if ((adcChannel & (1 << channel)) != 0) // 检查通道是否启用
                {
                    byte currentChannel = channel; // 创建局部变量避免闭包问题
                    tasks[channel] = Task.Run(() =>
                    {
                        bool readSuccess = false;
                        while (!readSuccess && !cts.Token.IsCancellationRequested)
                        {
                            readSuccess = DAQ217_TryReadData_Batch(device, currentChannel, channelData[currentChannel], readSize);
                            if (readSuccess)
                            {
                                // 计算非零数据的数量
                                int validDataCount = channelData[currentChannel].Count(x => x != 0);
                                
                                Console.WriteLine($"通道 {currentChannel + 1} 数据读取成功");
                                Console.WriteLine($"通道 {currentChannel + 1} 总数据长度: {readSize}");
                                Console.WriteLine($"通道 {currentChannel + 1} 非零数据长度: {validDataCount}");
                                
                                // 打印前10个数据点作为示例
                                Console.WriteLine($"通道 {currentChannel + 1} 的前10个数据点:");
                                for (int i = 0; i < Math.Min(10, readSize); i++)
                                {
                                    Console.WriteLine($"数据点 {i}: {channelData[currentChannel][i]:F3}V");
                                }
                            }
                            else
                            {
                                Thread.Sleep(10); // 读取失败时等待1ms再试
                            }
                        }
                    }, cts.Token);
                }
            }

            // 等待用户输入来停止采集
            Console.WriteLine("按任意键停止采集...");
            Console.ReadKey();
            
            // 取消所有线程
            cts.Cancel();
            
            try
            {
                // 等待所有任务完成
                Task.WaitAll(tasks.Where(t => t != null).ToArray());
            }
            catch (AggregateException)
            {
                // 忽略取消导致的异常
            }
        }

        // 停止采集
        if(!DAQ217_StopCollection(device)){
            Console.WriteLine("停止采集失败");
        }

        Console.WriteLine("按任意键继续...");
        Console.ReadKey();


        DAQ217Wrapper.DAQ217_Delete(device);
        USBServerWrapper.USBServer_Delete(usb_server);
        Console.ReadLine();
    }




    public static void Main(string[] args)
    {
        DAQ217();
    }
}